package com.bryanbibat.flashcards.spring;

import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;

import javax.jdo.JDOObjectNotFoundException;
import javax.jdo.PersistenceManager;

import org.json.JSONArray;
import org.json.JSONException;
import org.springframework.orm.jdo.support.JdoDaoSupport;
import org.springframework.stereotype.Repository;

@Repository
public class DeckServiceImpl extends JdoDaoSupport implements DeckService {

  private static final Logger log = Logger.getLogger(DeckServiceImpl.class.getName());
  
  @Override
  public Deck getDeck(String id) {
    PersistenceManager pm = getPersistenceManager();
    Deck deck = null;
    try {
      deck = pm.getObjectById(Deck.class, id);
      log.info(deck.getJsonData());
    } catch (JDOObjectNotFoundException e) {
      log.info("Deck not found");
    } finally {
      releasePersistenceManager(pm);
    }
    return deck;
  }
  
  @SuppressWarnings("unchecked")
  @Override
  public List<Deck> getAll() {
    PersistenceManager pm = getPersistenceManager();
    String query = "select from " + Deck.class.getName() + " order by id";
    List<Deck> decks = (List<Deck>) pm.newQuery(query).execute();
    
    if (log.isLoggable(Level.INFO)) {
      log.info("returning " + decks.size() + " decks");
      for (Deck deck: decks) {
        log.info(deck.toString());
      }
    }
    return decks;
  }

  @Override
  public void saveDeck(Deck deck) {
    preprocessDeck(deck);
    if (isNew(deck)) {
      insertDeck(deck);
    } else {
      updateDeck(deck);
    }
  }
  
  private void preprocessDeck(Deck deck) {
    try {
      JSONArray json = new JSONArray(deck.getJsonData());
      deck.setJsonData(json.toString());
    } catch (JSONException e) {
      e.printStackTrace();
    }
    
  }

  private boolean isNew(Deck deck) {
    return getDeck(deck.getId()) == null;
  }

  private void insertDeck(Deck deck) {
    PersistenceManager pm = getPersistenceManager();
    try {
      pm.makePersistent(deck);
    } catch (Exception e) {
      log.log(Level.SEVERE, "Error inserting deck", e);
    } finally {
      releasePersistenceManager(pm);
    }
  }
  
  private void updateDeck(Deck deck) {
    PersistenceManager pm = getPersistenceManager();
    try {
      Deck orig = pm.getObjectById(Deck.class, deck.getId());
      if (orig.getReadonly() != null && orig.getReadonly()) {
        return;
      }
      orig.setTitle(deck.getTitle());
      orig.setJsonData(deck.getJsonData());
 
    } catch (Exception e) {
      log.severe("Error updating deck");
    } finally {
      releasePersistenceManager(pm);
    }
  }

  @Override
  public void deleteDeck(String id) {
    PersistenceManager pm = getPersistenceManager();
    try {
      Deck deck = pm.getObjectById(Deck.class, id);
      if (deck.getReadonly() != null && deck.getReadonly()) {
        return;
      }
      pm.deletePersistent(deck);
 
    } catch (Exception e) {
      log.severe("Error deleting deck");
    } finally {
      releasePersistenceManager(pm);
    }
    
  }

}
